package com.flexandair.view
{
	import com.flexandair.ApplicationFacade;
	import com.flexandair.model.ClassesProxy;
	import com.flexandair.templates.CodeFactory;
	import com.flexandair.templates.CustomObjectFile;
	import com.flexandair.templates.ObjectProperty;
	import com.flexandair.view.components.ClassModel;
	import com.flexandair.view.components.ClassProp;
	import com.flexandair.view.components.ObjectDesignerCanvas;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.events.FlexEvent;
	
	import org.puremvc.as3.interfaces.IMediator;
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;

	public class CRUDdyBuddyMediator extends Mediator implements IMediator
	{
		public static const NAME:String = "CRUDdyBuddyMediator";
	
		private var file:File;
		private var cfInstance:CodeFactory = CodeFactory.getInstance();
		public function CRUDdyBuddyMediator(mediatorName:String=null, viewComponent:Object=null)
		{
			super(mediatorName, viewComponent);
		}
		
		override public function getMediatorName():String
		{
			return NAME;
		}
		
		override public function getViewComponent():Object
		{
			return null;
		}
		
		override public function setViewComponent(viewComponent:Object):void
		{
		}
		
		override public function listNotificationInterests():Array
		{
			return [ApplicationFacade.DATABASE_PROFILE_SELECTED,
					ClassesProxy.GET_CLASSES_SUCCESS,
					ClassesProxy.NO_CLASSES_FOUND,
					ClassesProxy.CLASS_ADDED
					];
		}
		
		override public function handleNotification(notification:INotification):void
		{	
			switch( notification.getName() )
			{
				case ApplicationFacade.DATABASE_PROFILE_SELECTED:
					this.cruddyBuddy.mainTN.selectedChild = this.cruddyBuddy.objectHolderCanvas;
					break;
				
				case ClassesProxy.GET_CLASSES_SUCCESS:
					this.assembleObjects( notification.getBody() as ArrayCollection  );
					break;
				
				case ClassesProxy.NO_CLASSES_FOUND:
					Alert.show("No classes found to generate.","Error");
					break;
					
				case ClassesProxy.CLASS_ADDED:
					cruddyBuddy.designerHolder.addChild( notification.getBody() as ObjectDesignerCanvas);
					break;
			}
		}
		
		override public function onRegister():void
		{
		 	cruddyBuddy.objectHolderCanvas.addEventListener( FlexEvent.CREATION_COMPLETE, onObjectHolderCreationComplete );
		 	cruddyBuddy.outputCanvas.addEventListener( FlexEvent.CREATION_COMPLETE, onOutputCanvasComplete );

		}
		
		private function onOutputCanvasComplete ( event:FlexEvent ) : void
		{
			cruddyBuddy.outputCanvas.removeEventListener( FlexEvent.CREATION_COMPLETE, onOutputCanvasComplete );
			cruddyBuddy.includeZend.addEventListener( MouseEvent.CLICK, showLicenseAlert ); 
		 	cruddyBuddy.browse.addEventListener( MouseEvent.CLICK, browseForOutput );
		 	cruddyBuddy.generateTrigger.addEventListener( MouseEvent.CLICK, onGenerateTriggerFire );
		}
		private function onGenerateTriggerFire ( event:MouseEvent ) : void
		{
			(facade.retrieveProxy( ClassesProxy.NAME ) as ClassesProxy).getClasses();	
		}
		
		
		public function assembleObjects( value:ArrayCollection ):void 
		{			
			var objectsForExport:Array = new Array();
			for each (var objectCanvas:ObjectDesignerCanvas in value) 
			{      	
	        	for each (var object:ClassModel in objectCanvas.classes) 
	        	{
	        		var customClass:CustomObjectFile = new CustomObjectFile();
	        		var propArray:Array = new Array();
	        		customClass.className = object.nameInput.text;
	        		customClass._dbTable = object.tableInput.text;
	        		
	        		if (object.createCB.selected == true) 
	        		{
	        			customClass.remoteMethods.push('create');
	        		}
	        		
	        		if (object.retrieveCB.selected == true) 
	        		{
	        			customClass.remoteMethods.push('retrieve');
	        		}
	        		
	        		if (object.updateCB.selected == true) 
	        		{
	        			customClass.remoteMethods.push('update');
	        		}
	        		
	        		if (object.deleteCB.selected == true) 
	        		{
	        			customClass.remoteMethods.push('delete');
	        		}
	        		
	        		for each (var property:ClassProp in object.childNodes) 
	        		{
	        			var prop:ObjectProperty = new ObjectProperty();
	        			prop.name = property.propNameInput.text;
	        			prop.dataType = property.propTypeCB.selectedLabel;
	        			prop.initialValue = property.initVal.text;
	        			propArray.push(prop);
	        		}
	        		
	        		customClass.classProperties = propArray;
	        		objectsForExport.push(customClass);
	        	}	        	
	        }
	        cfInstance.objectArray = objectsForExport;
	       if ( value && value.length > 0 )
	       {
	       		generate();
	       } 
	        
	 	}
	 

		private function generate( event:MouseEvent = null ):void 
		{
			//assembleObjects();
			cfInstance.voPath = cruddyBuddy.packagePathInput.text;
			cfInstance.createFolders();
			if ( cruddyBuddy.includeZend.selected == true ) 
			{
				var zf:File = File.applicationDirectory.resolvePath('ZF/Zend');
				zf.copyTo(new File(cruddyBuddy.outputFolder.text + "/Zend"));
				Alert.show("Files and folders successfully created in "+ cruddyBuddy.outputFolder.text +". You can now set up your application.","Finished!");
			}
			else 
			{
				Alert.show("Files and folders successfully created in "+ cruddyBuddy.outputFolder.text +". You can now set up your application.","Finished!");
			}
		}
		
		private function browseForOutput( event:MouseEvent ):void 
		{
			file = new File();
			file.addEventListener(Event.SELECT, dirSelected, false, 0, true); 
			file.browseForDirectory( "Select a directory" ); 
		}
		
		private function dirSelected( event:Event ):void 
		{ 
			file.removeEventListener(Event.SELECT, dirSelected);
		    cfInstance.outputDirectory = file.nativePath;
		    cruddyBuddy.outputFolder.text = file.nativePath;
		}
		
		private function onObjectHolderCreationComplete( event:FlexEvent ) : void 
		{
			cruddyBuddy.objectHolderCanvas.removeEventListener( FlexEvent.CREATION_COMPLETE, onObjectHolderCreationComplete );
			sendNotification(ApplicationFacade.ADD_OBJECT_DESIGNER_CANVAS);
		}
		
		override public function onRemove():void
		{
		}
		
		public function get cruddyBuddy() : CRUDdyBuddy
		{
			return viewComponent as CRUDdyBuddy;
		}
		
		private function showLicenseAlert( event:MouseEvent ):void 
	 	{
			if (cruddyBuddy.includeZend.selected == true) 
			{
				Alert.show("By selecting this option, you agree to the terms of the Zend Framework License, available at http://framework.zend.com/license.","Zend Framework License");
			}
		}
	}
}